package com.syp.auth.common.dbrouter.router;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import com.syp.auth.common.dbrouter.DBContextHolder;
import com.syp.auth.common.dbrouter.DBRouter;
import com.syp.auth.common.dbrouter.bean.DBRule;
import com.syp.auth.common.dbrouter.utils.DBRouterUtils;

//@Service("dbRouter")
public class TradeDBRouterImpl implements DBRouter, ApplicationContextAware {

	private static final Logger logger = LoggerFactory.getLogger(TradeDBRouterImpl.class);

	private ApplicationContext applicationContext;

	@Override
	public String doRoute(String fieldId, String dbRuleName) {

		DBRule dbRule = applicationContext.getBean(dbRuleName, DBRule.class);

		if (fieldId == null || dbRule == null || dbRule.getDataSourceKeys() == null || dbRule.getDataSourceKeys().size() <= 0) {
			throw new IllegalArgumentException("dbsCount and tablesCount must be both positive!");
		}
		try {
			// 对分库分表字段哈希后取绝对值
			int hashValue = DBRouterUtils.getHashValue(fieldId);
			// 用字段哈希后绝对值对总表数取余数，再除每库表数取商数，得到库索引值
			int dbIndex = DBRouterUtils.getDBIndex(dbRule, hashValue);
			// 用字段哈希后绝对值对每库表数取余数，由于数据源设置是从1开始，所以后面+1操作
			int tableIndex = DBRouterUtils.getTableIndex(dbRule, hashValue);
			// 获取对应的dataSource的KEY值
			String dsKey = dbRule.getDataSourceKeys().get(dbIndex);
			// 设置为dbKey对应的数据源为当前数据源
			DBContextHolder.setDbKey(dsKey);
			String tableFormat = DBRouterUtils.formatTableName(dbRule.getTableNameStyle(), tableIndex);
			DBContextHolder.setTableIndex(tableFormat);
			logger.info("DBRouter,fieldId:{},hashCode:{}", fieldId, hashValue);
			logger.info("DBRouter,dsKey:{},tableFormat:{}", dsKey, tableFormat);
			return dsKey;

		} catch (Exception e) {
			logger.error("DBRouter error,fieldId:{},Exception:{}", fieldId, e);
		}
		return null;
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext = applicationContext;
	}
}
